<template>
  <div class="dgg-image-upload">
    <el-upload
      action="#"
      list-type="picture-card"
      :class="{ hide: hideUploadBtn }"
      :file-list="fileList"
      :limit="limit"
      :on-preview="onPreview"
      :on-remove="onRemove"
      :http-request="onHTTPRequest"
      :on-success="onSuccess"
    >
      <i class="el-icon-plus"></i>
    </el-upload>

    <div
      v-show="loading"
      style="
        position: absolute;
        top: 0;
        width: 148px;
        height: 148px;
        display: flex;
        border-radius: 6px;
        justify-content: center;
        align-items: center;
        background-color: rgba(0, 0, 0, 0.5);
      "
      :style="{ left: fileList.length * (148 + 8) + 'px' }"
    >
      <el-progress
        type="dashboard"
        :percentage="percentage"
        :color="[
          { color: '#f56c6c', percentage: 20 },
          { color: '#e6a23c', percentage: 40 },
          { color: '#5cb87a', percentage: 60 },
          { color: '#1989fa', percentage: 80 },
          { color: '#6f7ad3', percentage: 100 },
        ]"
      ></el-progress>
    </div>

    <el-dialog :visible.sync="showDialog" :show-close="false">
      <img :src="imgUrl" alt="" style="width: 100%" />
    </el-dialog>
  </div>
</template>

<script>
import COS from 'cos-js-sdk-v5';
const cos = new COS({
  SecretId: 'AKIDVoxta1FIBrJXWDgy1pNhofHUVIOErGPJ',
  SecretKey: 'lJdhYBZ5MQGrBIAoCNJ0rUu51jGbjdLq',
});

export default {
  name: 'DggImageUpload',
  props: {
    value: [String, Array], // String: 'http://xxxx1'    Array: [ 'http://xxxx1', 'http://xxxx2' ]
    limit: {
      type: Number,
      default: 1,
    },
  },
  data() {
    // props 在 data 之前解析，所以在 data 函数中可以拿到 props 数据

    let fileList = [];

    if (!!this.value) {
      if (typeof this.value === 'string') {
        fileList.push({ url: this.value });
      } else {
        fileList = this.value.map(v => ({ url: v }));
      }
    }

    return {
      loading: false, // 控制是否正在上传中
      percentage: 0, // 1-100
      imgUrl: '',
      showDialog: false,
      fileList,
    };
  },
  computed: {
    hideUploadBtn() {
      // 如果正在上传中
      // 或者 已上传的文件列表的长度 等于 最大限制数量
      // 或者 传给我的 this.value 是一个字符串 并且 已上传的文件列表长度为 1
      // 就隐藏上传按钮
      return (
        this.loading ||
        this.fileList.length === this.limit ||
        (typeof this.value === 'string' && this.fileList.length === 1)
      );
    },
  },
  methods: {
    onSuccess(response, file, fileList) {
      this.fileList = fileList;
      this.emitVModelEvent();
    },
    async onHTTPRequest({ file }) {
      this.loading = true;

      const { Location } = await cos.putObject({
        Bucket: 'leimf-001-1317063555', // 哪个桶
        Region: 'ap-guangzhou', // 哪个地域
        Key: `${file.uid}_${file.name}`, // 上传的唯一键名
        Body: file, // 文件对象
        onProgress: params => {
          this.percentage = Math.floor(params.percent * 100);
        },
      });

      this.loading = false;

      return `http://${Location}`;
    },
    onPreview(file, fileList) {
      this.imgUrl = file.url;
      this.showDialog = true;
    },
    onRemove(file, fileList) {
      this.fileList = fileList;
      this.emitVModelEvent();
    },
    emitVModelEvent() {
      if (typeof this.value === 'string') {
        // 因为触发 v-model 的 input 有两种情况：
        // 1. 删除的时候
        //    1.1 this.value 是一个字符串
        //      this.fileList 就是个空数组 ==> 就给空字符串
        //    1.2 this.value 是一个数组
        //      this.fileList 就是剩下的文件数组  逻辑不变
        // 2. 添加文件
        //    1.1 this.value 是一个字符串
        //      this.fileList 就是添加之后的文件数组 ==> 给数组第一项的 response
        //    1.2 this.value 是一个数组
        //      this.fileList 就是现有的文件数组  逻辑不变
        this.$emit('input', this.fileList[0]?.response || '');
      } else {
        this.$emit(
          'input',
          this.fileList.map(v => v.response || v.url)
        );
      }
    },
  },
  created() {
    if (typeof this.value === 'string' && this.limit !== 1) {
      this.$destroy();
      throw new Error('怎么回事？？？给个字符串，长度不是1？');
    }
  },
};
</script>

<style lang="scss" scoped>
.dgg-image-upload {
  position: relative;

  ::v-deep .el-progress__text {
    color: white;
  }

  ::v-deep .el-dialog__header {
    background: transparent;
  }

  ::v-deep .el-dialog__body {
    padding: 0;
  }

  .hide {
    ::v-deep .el-upload--picture-card {
      display: none;
    }
  }
}
</style>
